package com.android.accessibility.function;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import android.annotation.SuppressLint;
import android.app.Notification;
import android.app.NotificationManager;
import android.content.Context;
import android.content.Intent;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Build;
import android.os.FileObserver;
import android.os.Handler;
import android.os.Looper;
import android.preference.PreferenceManager;
import android.support.v4.app.NotificationCompat;
import android.text.TextUtils;

import com.android.accessibility.PhoneManager;
import com.android.accessibility.R;
import com.android.accessibility.activity.GlobalTipActivity;
import com.android.accessibility.ad.ForwardChecker;
import com.android.accessibility.service.WXObserverService;
import com.android.accessibility.stat.Stat;
import com.android.accessibility.utils.AppConfig;
import com.android.accessibility.utils.Constant;
import com.android.accessibility.utils.Log;
import com.android.accessibility.utils.Utils;

public class WXOnekeyforwardingVideo {

    @SuppressLint("SimpleDateFormat")
    private final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    private int mMask = FileObserver.CREATE | FileObserver.CLOSE_WRITE
            | FileObserver.DELETE;
    private List<FileObserver> mObserverList;
    private List<String> mObservePath = null;

    private static final String FORWARD_VIDEO_EXT = ".mp4";
    private static final String FORWARD_VIDEO_THUMB_EXT = ".jpg";

    private static final String RECORD_VIDEO_EXT = ".mp4";
    private static final String RECORD_VIDEO_THUMB_EXT = ".mp4.thumb";

    private String mForwradVideo;
    private String mForwradVideoThumb;

    private String mRecordVideo;
    private String mRecordVideoThumb;

    private Context mContext;
    private NotificationManager mNM;

    public WXOnekeyforwardingVideo(Context context) {
        mContext = context;
        mNM = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
    }

    /**
     * 查询转发的视频文件路径
     * @param event
     * @param path
     */
    private void findForwardVideo(int event, String path) {
        if (event == FileObserver.CREATE) {
            if (path.toLowerCase(Locale.ENGLISH).endsWith(FORWARD_VIDEO_EXT)) {
                mForwradVideo = path;
            } else if (path.toLowerCase(Locale.ENGLISH).endsWith(FORWARD_VIDEO_THUMB_EXT)) {
                mForwradVideoThumb = path;
            }
        }
    }

    /**
     * 查询录制的视频文件路径
     * @param event
     * @param path
     */
    private void findRecordVideo(int event, String path) {
        if (TextUtils.isEmpty(mForwradVideo)
                || TextUtils.isEmpty(mForwradVideoThumb)) {
            return;
        }
        if (event == FileObserver.CLOSE_WRITE) {
            if (path.toLowerCase(Locale.ENGLISH).endsWith(RECORD_VIDEO_EXT)) {
                mRecordVideo = path;
            } else if (path.toLowerCase(Locale.ENGLISH).endsWith(RECORD_VIDEO_THUMB_EXT)) {
                mRecordVideoThumb = path;
            }
            if (!TextUtils.isEmpty(mRecordVideo)
                    && !TextUtils.isEmpty(mRecordVideoThumb)) {
                processRecordVideo();
            }
        }
    }

    /**
     * 处理录制文件
     */
    private void processRecordVideo() {
        String packageName = Utils.getTopPackage(mContext);
        if (TextUtils.isEmpty(packageName) || packageName.equals(Constant.WX_PACKAGENAME) || true) {
            processRecordVideoLocked();
        }
    }

    /**
     * 在通知栏显示视频转发情况
     * @param delete
     * @param rename
     * @param success
     */
    @SuppressWarnings("unused")
    private void showSuccessNotification(boolean delete, boolean rename, boolean success) {
        if (mContext == null) {
            return;
        }
        Uri uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
        NotificationCompat.Builder builder = new NotificationCompat.Builder(mContext);
        builder.setSmallIcon(R.drawable.ic_launcher);
        builder.setAutoCancel(true);
        builder.setTicker(success ? "视频替换成功" : "视频替换失败");
        builder.setContentTitle(success ? "视频替换成功" : "视频替换失败");
        String deleteText = delete ? "删除原视频成功" : "删除原视频失败";
        String renameText = rename ? "重命名成功" : "重命名失败";
        builder.setContentText(deleteText + "," + renameText);
        builder.setSound(uri);
        Notification notification = builder.build();
        mNM.notify(R.drawable.ic_launcher, notification);
        if (success) {
            deleteSuccessNotification();
        }
    }

    private void deleteSuccessNotification() {
        if (mContext == null) {
            return;
        }
        Handler handler = new Handler(Looper.getMainLooper());
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                mNM.cancel(R.drawable.ic_launcher);
            }
        }, 5000);
    }

    private void showForwardResult(boolean delete, boolean rename,
            long forwardVideoSize, long recordVideoSize, boolean success) {
        String resultTip = null;
        if (!success) {
            String size1 = Utils.formatAppSize(forwardVideoSize, "转发的视频大小 : ");
            String size2 = Utils.formatAppSize(recordVideoSize, "录制的视频大小 : ");
            String deleteText = delete ? "删除原视频成功" : "删除原视频失败";
            String renameText = rename ? "重命名视频成功" : "重命名视频失败";
            resultTip = size1 + "\n" + size2 + "\n" + deleteText + "\n" + renameText;
        }
        startGlobalTipActivity(success, resultTip);
    }

    private void startGlobalTipActivity(boolean success, String resultTip) {
        if (mContext == null) {
            return;
        }
        final Intent intent = new Intent(mContext, GlobalTipActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
        intent.putExtra("forward_result", success);
        if (!TextUtils.isEmpty(resultTip)) {
            intent.putExtra("failure_tip", resultTip);
        }
        Handler handler = new Handler(Looper.getMainLooper());
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                mContext.startActivity(intent);
            }
        }, 1000);
    }

    private void processRecordVideoLocked() {
        Log.d(Log.TAG, "mForwradVideo      : " + mForwradVideo);
        Log.d(Log.TAG, "mForwradVideoThumb : " + mForwradVideoThumb + "\n");
        Log.d(Log.TAG, "mRecordVideo       : " + mRecordVideo);
        Log.d(Log.TAG, "mRecordVideoThumb  : " + mRecordVideoThumb + "\n");

        AppConfig config = AppConfig.get(mContext);
        if (config.isForceStop()) {
            Intent intent = new Intent(mContext, WXObserverService.class);
            mContext.stopService(intent);
            return;
        }

        boolean allowForward = ForwardChecker.get(mContext).allowForward();
        if (!allowForward) {
            Intent intent = new Intent(mContext, WXObserverService.class);
            mContext.stopService(intent);
            startGlobalTipActivity(false, "当前积分余额不足");
            return;
        }

        File forwardVideo = new File(mForwradVideo);
        File forwardVideoThumb = new File(mForwradVideoThumb);
        File recordVideo = new File(mRecordVideo);
        File recordVideoThumb = new File(mRecordVideoThumb);
        setWritable(forwardVideo);
        setWritable(forwardVideoThumb);
        setWritable(recordVideo);
        setWritable(recordVideoThumb);
        boolean r1 = false;
        boolean r2 = false;
        boolean r3 = false;
        boolean r4 = false;

        long forwardVideoSize = 0;
        long recordVideoSize = 0;
        if (forwardVideo.exists()) {
            forwardVideoSize = forwardVideo.length();
        }
        if (recordVideo.exists()) {
            recordVideoSize = recordVideo.length();
        }

        if (recordVideo.exists()) {
            r1 = recordVideo.delete();
            if (recordVideo.exists()) {
                r1 = deleteFileSafely(recordVideo);
            }
        }
        if (recordVideoThumb.exists()) {
            r2 = recordVideoThumb.delete();
            if (recordVideoThumb.exists()) {
                r2 = deleteFileSafely(recordVideoThumb);
            }
        }

        r3 = forwardVideo.renameTo(recordVideo);
        r4 = forwardVideoThumb.renameTo(recordVideoThumb);

        boolean keepOldVideo = PreferenceManager.getDefaultSharedPreferences(
                mContext).getBoolean("keep_oldvideo", false);
        if (keepOldVideo) {
            Utils.copyFile(recordVideoThumb.getAbsolutePath(), forwardVideoThumb.getAbsolutePath());
            Utils.copyFile(recordVideo.getAbsolutePath(), forwardVideo.getAbsolutePath());
        }
        mForwradVideo = null;
        mForwradVideoThumb = null;
        mRecordVideo = null;
        mRecordVideoThumb = null;
        Map<String, Object> params = new HashMap<String, Object>();
        String hashCode = PhoneManager.get(mContext).getAndroidIDHashCode();
        params.put("forward", Build.MODEL + " -- " + hashCode + " |" + r1 + "|" + r2 + "|" + r3 + "|" + r4);
        Stat.get(mContext).reportKVEvent("onekeyforward", params);

        boolean success = r1 && r2 && r3 && r4;
        showForwardResult(r1 && r2, r3 && r4, forwardVideoSize, recordVideoSize, success);
        if(success) {
            ForwardChecker.get(mContext).spentIntegral();
            params = new HashMap<String, Object>();
            hashCode = PhoneManager.get(mContext).getAndroidIDHashCode();
            params.put("forwarddetail", hashCode + " -- " + sdf.format(new Date()));
            Stat.get(mContext).reportKVEvent("onekeyforward", params);
        }
    }

    private void setWritable(File file) {
        try {
            if (file != null && file.exists()) {
                file.setWritable(true, false);
            }
        } catch(Exception e) {
            Log.d(Log.TAG, "error : " + e);
        }
    }

    /**
     * 安全删除文件.
     * @param file
     * @return
     */
    public static boolean deleteFileSafely(File file) {
        try {
            if (file != null) {
                String tmpPath = file.getParent() + File.separator
                        + System.currentTimeMillis();
                File tmp = new File(tmpPath);
                file.renameTo(tmp);
                return tmp.delete();
            }
        } catch (Exception e) {
            Log.d(Log.TAG, "error : " + e);
        }
        return false;
    }

    public void startOnekeyForward() {
        mObservePath = Utils.readVideoDir(mContext);
        if (mObservePath == null || mObservePath.size() <= 0) {
            Map<String, Object> params = new HashMap<String, Object>();
            String hashCode = PhoneManager.get(mContext).getAndroidIDHashCode();
            params.put("emptyobserver", Build.MODEL + " -- " + hashCode);
            Stat.get(mContext).reportKVEvent("onekeyforward", params);
            return;
        }

        mObserverList = new ArrayList<FileObserver>();
        for (String path : mObservePath) {
            mObserverList.add(startObserver(path));
        }
    }

    private FileObserver startObserver(final String observerPath) {
        Log.d(Log.TAG, "path : " + observerPath);
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("observer_path", Build.MODEL + " -- " + observerPath);
        Stat.get(mContext).reportKVEvent("onekeyforward", params);
        FileObserver observer = new FileObserver(observerPath, mMask) {
            @Override
            public void onEvent(int event, String path) {
                if (path == null) {
                    return;
                }
                if (path.toLowerCase(Locale.ENGLISH).startsWith("tempvideo")) {
                    findRecordVideo(event,
                            new File(observerPath, path).getAbsolutePath());
                } else {
                    findForwardVideo(event,
                            new File(observerPath, path).getAbsolutePath());
                }
            }
        };
        observer.startWatching();
        return observer;
    }

    public void stopOnekeyForward() {
        if (mObserverList == null) {
            return;
        }
        for (FileObserver o : mObserverList) {
            stopObserver(o);
        }
    }

    private void stopObserver(FileObserver observer) {
        if (observer != null) {
            observer.stopWatching();
        }
    }
}
